package userlogic

import (
	"context"

	"go-zero-admin/apps/system/cmd/rpc/internal/logic/userpost"
	"go-zero-admin/apps/system/cmd/rpc/internal/svc"
	"go-zero-admin/apps/system/cmd/rpc/syspb"
	"go-zero-admin/apps/system/model"
	"go-zero-admin/pkg/tool"
	"go-zero-admin/pkg/xerr"

	"github.com/duke-git/lancet/v2/validator"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

type UpUserDataLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
	isExNameOrMobileOrEmailLogic *IsExNameOrMobileOrEmailLogic
	getUserPostListLogic         *userpostlogic.GetUserPostListLogic
	addUserDataLogic             *AddUserDataLogic
}

func NewUpUserDataLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpUserDataLogic {
	return &UpUserDataLogic{
		ctx:                          ctx,
		svcCtx:                       svcCtx,
		Logger:                       logx.WithContext(ctx),
		isExNameOrMobileOrEmailLogic: NewIsExNameOrMobileOrEmailLogic(ctx, svcCtx),
		getUserPostListLogic:         userpostlogic.NewGetUserPostListLogic(ctx, svcCtx),
		addUserDataLogic:             NewAddUserDataLogic(ctx, svcCtx),
	}
}

func (l *UpUserDataLogic) UpUserData(in *syspb.UpUserDataReq) (*syspb.UpUserDataResp, error) {
	user := in.GetParams()
	if user == nil || user.GetId() == 0 || user.GetUserName() == "" || user.GetUserNickname() == "" ||
		user.GetMobile() == "" || !validator.IsChineseMobile(user.GetMobile()) ||
		user.GetUserEmail() == "" || !validator.IsEmail(user.GetUserEmail()) ||
		user.GetUpdateUser() == "" {
		return nil, errors.Wrapf(xerr.NewErrMsg("更新用户失败：参数缺失"),
			tool.GetErrMsgFormat("insert user"), "params is not existed", in)
	}

	// 检验重复
	isExistResp, err := l.isExNameOrMobileOrEmailLogic.IsExNameOrMobileOrEmail(&syspb.IsExNameOrMobileOrEmailReq{
		UserName: user.GetUserName(),
		Mobile:   user.GetMobile(),
		Email:    user.GetUserEmail(),
		IsNotId:  user.GetId(),
	})
	if err != nil {
		return nil, err
	}
	if isExistResp.GetIsExist() {
		return nil, errors.Wrapf(xerr.NewErrMsg("更新用户："+user.UserName+" 失败，用户名称或手机号或邮箱已存在"),
			tool.GetErrMsgFormat("update user"), "user name or mobile or email is existed", user)
	}

	// 数据转换
	one, err := l.svcCtx.SysUserModel.FindOne(l.ctx, user.GetId())
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrFindOneCode(err, model.ErrNotFound),
			tool.GetErrMsgFormat("update user"), err, in)
	}
	one.Mobile = user.GetMobile()
	one.UserNickname = user.GetUserNickname()
	one.Birthday = user.GetBirthday()
	one.UserStatus = user.GetUserStatus()
	one.UserEmail = user.GetUserEmail()
	one.Sex = user.GetSex()
	one.Avatar = user.GetAvatar()
	one.DeptId = user.GetDeptId()
	one.Remark = user.GetRemark()
	one.UpdateUser = user.GetUpdateUser()

	// 更新
	if err = l.svcCtx.SysUserModel.Trans(l.ctx, func(context context.Context, session sqlx.Session) error {
		// 更新用户信息
		e := l.svcCtx.SysUserModel.UpdateEx(l.ctx, session, one)
		if e != nil {
			return e
		}

		// 设置用户岗位
		e = l.addUserDataLogic.HandleUserPost(in.GetPostIds(), user.GetId(), true, session)
		if e != nil {
			return e
		}

		// 设置用户所属角色信息
		e = l.addUserDataLogic.HandleUserRole(in.GetRoleIds(), user.GetId(), true, session)
		if e != nil {
			return e
		}

		return nil
	}); err != nil {
		return nil, errors.Wrapf(xerr.NewErrFindOneCode(err, model.ErrNotFound),
			tool.GetErrMsgFormat("update user"), err, in)
	}

	return &syspb.UpUserDataResp{}, nil
}
